import * as zipper from "zip-local";
import { BasePack } from "../BasePack";
import { IPackageOptions } from "../IPack";
import { cpDir, cpFile } from "../../utils/CpFile";
import { join } from "path";
import { readFileSync, writeFileSync, statSync, readdirSync } from "fs";
import { paserIndexJs } from "../../utils/PaserFile";

export class TtPack extends BasePack {

    protected _enginePluginVers = [];// 当前实现的引擎版本

    constructor(packProjectJsonName: string) {
        super(packProjectJsonName);
        this._projectConfigFile = 'project.config.json';
        this._layaEnginePlugins = [
        ];
        this._initEnginePluginVers()
    }

    protected _initEnginePluginVers() {
        // 提取当前引擎版本包的版本列表
        let from = this._getEnginePluginUrl();
        let verions: string[] = [];
        let stat = statSync(from)
        if (stat.isDirectory()) {
            let files = readdirSync(from)
            for (const ifile of files) {
                let temp = ifile.match(/\d(\.\d+)+/);
                if (temp) verions.push(temp[0]);
            }
        }
        this._enginePluginVers = verions;
    }

    /** 拷贝初始化内容到项目目录中 */
    protected _copyInitDir(from: string, out: string) {
        let po: IPackageOptions = this._projCfg[this._mode]['packageOptions'];

        cpDir(from, out, () => {
            // 需要修改一下 project.config.json 中的替换文本
            let pcfUrl = `${this._plat}/${this._plat}game/${this._projectConfigFile}`;
            let pcfTemp = join(this._packOpt.outputPath, pcfUrl);
            let jsonStr = readFileSync(pcfTemp).toString();

            jsonStr = jsonStr.replace('${APPID}', this._projCfg.init.appid)
            jsonStr = jsonStr.replace('${PROJECT_NAME}', this._projCfg.init.projectName);
            writeFileSync(pcfTemp, jsonStr);

            this._startPack(po);
        })
    }

    protected _startPack(packOpt: IPackageOptions) {
        this._minigamePath = join(this._packOpt.outputPath, `${this._plat}/${this._plat}game`);
        this._setIndexJs()
        this._setGameJson();
        // this._setGameConfig();//这里修改了要将设置config放到copyjs之后
        this._copyJs()
    }

    protected _setGameConfig(configUrl?: string) {
        let config: any = this._projCfg[this._mode]['config'];

        if (!config) {
            config = {};
            return;
        }
        let txt = `window.config = ${JSON.stringify(config)};\n`;
        let po = this._projCfg[this._mode]['packageOptions'];
        configUrl = configUrl ? configUrl : join(po.outputPath, `${this._plat}/${this._plat}game`, 'config.js');
        writeFileSync(configUrl, txt);
    }
    protected _copyJs() {
        let fromIndex = join(this._packOpt.projectBin, 'index.js');
        let { jslist } = paserIndexJs(fromIndex, this._layaEnginePlugins, !!this._packOpt.enginePlugin);

        // 将index中的需要用到的js拷贝到wxgame项目中
        let from: string[] = [];
        let to: string[] = [];
        jslist.forEach(url => {
            from.push(join(this._packOpt.projectBin, url))
            let libUrl = join(this._minigamePath, url);
            to.push(libUrl);
        });

        cpFile(from, to, () => {

            if (this._packOpt.skipResCheck) {
                console.log(this._mode + ' pack over');
                this._setGameConfig();
                this._packOver()
                return;
            } else {
                this._resPath = this._packOpt.resPath;
                this._cpResIndex = 0;
                // delDir(join(this._minigamePath, 'res'));// 拷贝资源文件前先删除原有res目录
                this._setGameConfig();
                this._cpRes();
            }

        }, !this._packOpt.skipCodeUglify, { file: this._layaEnginePlugins })
    }

    protected _setGameJson() {
        let gamejsonUrl = join(this._packOpt.outputPath, `${this._plat}/${this._plat}game`, 'game.json');
        let gamejson = JSON.parse(readFileSync(gamejsonUrl).toString());
        // 判断引擎插件版本是否修改
        if (!!this._packOpt.enginePlugin) {
            if (gamejson.plugins && gamejson.plugins.layaPlugin) {
                gamejson.plugins.layaPlugin.version = this._packOpt.enginePlugin;
            } else {
                gamejson.plugins = {
                    layaPlugin: {
                        version: this._packOpt.enginePlugin,
                        provider: "wx70d8aa25ec591f7a",
                        path: "laya-libs"
                    }
                }
            }
        } else {
            // 不需要引擎插件的情况，将game.json中的插件部分清掉
            delete gamejson.plugins;
        }
        let gameJsonSetting = this._projCfg[this._mode]['gameJson'];
        for (let key in gameJsonSetting) {
            if (!!gameJsonSetting[key]) {
                // 如果配置数据存在，使用配置数据
                gamejson[key] = gameJsonSetting[key];
            } else {
                delete gamejson[key];
            }
        }

        writeFileSync(gamejsonUrl, JSON.stringify(gamejson));
    }

    protected _setIndexJs() {
        // 修改index.js
        let fromIndex = join(this._packOpt.projectBin, 'index.js');
        let { index_txt, plugin_txt, plugin_list } = paserIndexJs(fromIndex, this._layaEnginePlugins, !!this._packOpt.enginePlugin);
        let outIndex = join(this._packOpt.outputPath, `${this._plat}/${this._plat}game`, 'index.js');
        writeFileSync(outIndex, index_txt);
        // console.log('_setIndexJs', plugin_txt);
        this._resetGameJs(plugin_txt)

        if (this._packOpt.enginePlugin) {
            let enginePluginVer = '2.4.0';// 默认是不用引擎插件
            if (typeof this._packOpt.enginePlugin == 'string') {
                if (this._enginePluginVers.indexOf(this._packOpt.enginePlugin) >= 0) {
                    enginePluginVer = this._packOpt.enginePlugin;
                } else {
                    console.log('配置的引擎插件版本不支持，目前只支持：', this._enginePluginVers.join(','));
                }
            }
            let enginePluginUrl = join(this._getEnginePluginUrl(), `laya-libs_${enginePluginVer}.zip`);
            console.log('url:', enginePluginUrl);
            zipper.sync.unzip(enginePluginUrl).save(this._minigamePath);
            // 清除不需要导入的引擎插件
            this._clearLayalibs(plugin_list)
        }

    }

    protected _resetGameJs(plugin_txt: string) {
        // 修改game.js

        let fromGamejsUrl = join(this._minigamePath, 'game.js');
        let gamejsTxt = readFileSync(fromGamejsUrl).toString();

        let searchTxt = /\/\/==START([\s\S]*?)\/\/==END/g
        gamejsTxt = gamejsTxt.replace(searchTxt, `//==START\n${plugin_txt}\n//==END`);
        writeFileSync(fromGamejsUrl, gamejsTxt);
    }

}